# 【一】介绍
# ● xpath在Python的爬虫学习中，起着举足轻重的地位
# 对比正则表达式 re两者可以完成同样的工作，实现的功能也差不多
# 但xpath明显比re具有优势，在网页分析上使re退居二线。
# ● xpath 全称为XML Path Language 一种小型的查询语言

# 【二】安装
# pip install lxml
# bs4的解析器 也是 lxml

# 【三】简单使用
"""
# 【1】导入
from lxml import etree
# 【2】使用
tree = etree.HTML("源码")

# 【3】写 xpath 表达式
tree.xpath("表达式")
"""

# 【四】路径表达式
# 区别 css 语法 空格作为分割 &gt; ~ 作为层级关系
# 以 / 和 // 来做表达式分割
'''
表达式	描述	实例	解析
/	从根节点选取	/body/div[1]	选取根结点下的body下的第一个div标签
//	从匹配选择的当前节点选择文档中的节点，而不考虑它们的位置	//a	选取文档中所有的a标签
./	当前节点再次进行xpath	./a	选取当前节点下的所有a标签
@	选取属性	//@class	选取所有的class属性
'''

# ul &gt; li
# ul ---&gt; li 的列表 / li 这一层 // ul 这一层 ./ 从 li 层开始找 @ 取当前标签的某个属性
'''

from lxml import etree

tree = etree.HTML(open("html_doc.html", "r").read())

# 获取到所有的a标签
print(tree.xpath("//a"))

# 获取到 p 标签下面的 a 标签
print(tree.xpath("/html/body/p/a"))
print(tree.xpath("//p/a"))

# 提取每个标签的 href 属性
for a in tree.xpath("//a"):
    print(a.xpath("./@href")[0])
    '''

# 【五】谓语
# ● 谓语用来查找某个特定的节点或者包含某个指定的值的节点。
# ● 谓语被嵌在方括号中。
# ● 在下面的表格中，我们列出了带有谓语的一些路径表达式，以及表达式的结果：
'''
路径表达式	结果
/ul/li[1]	选取属于 ul子元素的第一个 li元素。
/ul/li[last()]	选取属于 ul子元素的最后一个 li元素。
/ul/li[last()-1]	选取属于 ul子元素的倒数第二个 li元素。
//ul/li[position()&lt;3]	选取最前面的两个属于 ul元素的子元素的 li元素。
//a[@title]	选取所有拥有名为 title的属性的 a元素。
//a[@title='xx']	选取所有 a元素，且这些元素拥有值为 xx的 title属性。
//a[@title&gt;10] &gt; &lt; &gt;= &lt;= !=	选取 a元素的所有 title元素，且其中的 title元素的值须大于 10。
/body/div[@price&gt;35.00]	选取body下price元素值大于35的div节点
'''
'''
from lxml import etree

tree = etree.HTML(open("html_doc.html", "r").read())

# 获取 p 标签下面的第一个  a 标签
print(tree.xpath("//p/a[1]/@href"))

# 获取 p 标签下面的最后一个  a 标签
print(tree.xpath("//p/a[last()]/@href"))
print(tree.xpath("//p/a[@name]/@href"))
print(tree.xpath("//p/a[@name='777']/@href"))
'''

# 【六】通配符
# * 代表任意元素节点
'''
通配符	描述
*	匹配任何元素节点。
@*	匹配任何属性节点。
node()	匹配任何类型的节点。
'''
from lxml import etree

tree = etree.HTML(open("html_doc.html", "r").read())
print(tree.xpath("//p[@class='story']/*"))
print(tree.xpath("//p[@*]/*"))

# 【七】或条件 和 且条件
print(tree.xpath("//a[@id='link1'] | //a[@id='link2']"))

# 逻辑运算
# 让某个标签具有 class="sister" and id="link1"
print(tree.xpath("//a[@class='sister' and @id='link1']"))

# 【八】模糊查询
print(tree.xpath("//p/a[contains(@id,'link')]"))
print(tree.xpath("//*[contains(@id,'link')]"))
